<template>
  <div class="rich_editor">
    <!-- 富文本编辑器： 适用于 WangEditor 4.x 版本 -->
    <div ref="editor"></div>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { useStore } from "vuex";
import config from "../config/index";
import WangEditor from "wangEditor";
// import hljs from "highlight.js";

export default {
  name: "RichEditor",
  props: {
    modelValue: {
      type: String,
      default: "",
    },
    height: {
      type: Number,
      default: 250,
    },
    businessKey: {
      type: String,
      default: "",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["update:modelValue"],
  setup(props, context) {
    const store = useStore();

    // 富文本编辑器
    const editor = ref(null);
    let instance;

    // 禁用编辑器
    const disable = () => {
      nextTick(() => {
        instance && instance.disable();
      });
    };

    // 解除禁用
    const enable = () => {
      nextTick(() => {
        instance && instance.enable();
      });
    };

    watch(
      () => props.disabled,
      (newVal) => {
        // console.log("watch ===> disabled", newVal);
        if (newVal) {
          disable();
        } else {
          enable();
        }
      },
      { immediate: true }
    );

    watch(
      () => props.modelValue,
      (newVal) => {
        // console.log("watch ===> modelValue", newVal);
        nextTick(() => {
          instance.txt.html(newVal); // 重新设置编辑器内容
        });
      },
      { immediate: true }
    );

    // 组件钩子
    onMounted(() => {
      instance = new WangEditor(editor.value);

      instance.config.zIndex = 1;
      // 设置编辑区域高度
      instance.config.height = props.height;
      // 配置 onchange 回调函数
      instance.config.onchange = function (newHtml) {
        context.emit("update:modelValue", newHtml);
      };
      // 配置触发 onchange 的时间频率，默认为 200ms
      instance.config.onchangeTimeout = 500; // 修改为 500ms

      // 挂载highlight插件
      // instance.highlight = hljs;

      /** ---------------------  上传图片 start ------------------------- */

      // 配置 server 接口地址
      instance.config.uploadImgServer = config.baseURL + "/upload/image";

      // 文件名
      instance.config.uploadFileName = "file";

      // 限制大小
      instance.config.uploadImgMaxSize = 1 * 1024 * 1024; // 2M

      // 限制类型
      instance.config.uploadImgAccept = [
        "jpg",
        "jpeg",
        "png",
        // "gif",
        // "bmp",
        // "webp",
      ];

      // 限制一次最多能传几张图片
      instance.config.uploadImgMaxLength = 5; // 一次最多上传 5 个图片

      // 自定义上传参数
      instance.config.uploadImgParams = {
        businessKey: props.businessKey,
        type: null,
      };

      // 是否需要将参数拼接到 url 中
      instance.config.uploadImgParamsWithUrl = false;

      // 自定义 header
      instance.config.uploadImgHeaders = {
        "login-token": store.state.user.token,
      };

      // 跨域是否传递 cookie ，默认为 false
      instance.config.withCredentials = false;

      // 超时时间，默认为 10 秒
      instance.config.uploadImgTimeout = 10 * 1000;

      // 上传图片的结果反馈
      instance.config.uploadImgHooks = {
        before: function (xhr, editor, files) {
          // 图片上传之前触发
          // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象，files 是选择的图片文件
          // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
          // return {
          // prevent: true,
          // msg: '放弃上传'
          // }
          // console.log("before ===> xhr", xhr);
          // console.log("before ===> editor", editor);
          // console.log("before ===> files", files);
        },
        success: function (xhr, editor, result) {
          // 图片上传并返回结果，图片插入成功之后触发
          // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象，result 是服务器端返回的结果
          // console.log("success ===> result", result);
        },
        fail: function (xhr, editor, result) {
          // 图片上传并返回结果，但图片插入错误时触发
          // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象，result 是服务器端返回的结果
          // console.log("fail ===> result", result);
          ElMessage.error("上传失败");
        },
        error: function (xhr, editor) {
          // 图片上传出错时触发
          // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象
          // console.log("error ===> xhr", xhr);
          // console.log("error ===> editor", editor);
          ElMessage.error("上传失败");
        },
        // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式，可使用该配置
        // （但是，服务器端返回的必须是一个 JSON 格式字符串！！！否则会报错）
        customInsert: function (insertImg, result, editor) {
          // 图片上传并返回结果，自定义插入图片的事件（而不是编辑器自动插入图片！！！）
          // insertImg 是插入图片的函数，参数editor 是编辑器对象，result 是服务器端返回的结果
          // console.log("customInsert ===> result", result);
          if (result.state === "0000" && result.data) {
            const url = config.fileDownloadUrl + "/" + result.data.filePath;
            insertImg(url);
          } else {
            ElMessage.error("上传失败");
          }
          // result 必须是一个 JSON 格式字符串！！！否则报错
        },
      };

      /** ---------------------  上传图片 end ------------------------- */

      instance.create();
    });

    onBeforeUnmount(() => {
      instance.destroy();
      instance = null;
    });

    return {
      editor,
      disable,
      enable,
    };
  },
};
</script>

<style lang="less" scoped>
.rich_editor {
}
</style>
